package com.example.matchingengine.controller;

import com.example.matchingengine.model.Order;
import com.example.matchingengine.service.OrderProducerService;
import com.example.matchingengine.service.dto.OrderRequest;
import io.micrometer.core.annotation.Timed;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * 订单控制器
 * 提供订单相关的API接口
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/orders")
public class OrderController {

    @Autowired
    private OrderProducerService orderProducerService;

    @Autowired
    private GenericObjectPool<Order> orderPool;

    /**
     * 创建订单
     * 接收订单请求，生成订单并发送到撮合引擎
     */
    @PostMapping
    @Timed(value = "api.order.create", description = "创建订单请求处理时间")
    public ResponseEntity<?> createOrder(@RequestBody OrderRequest request) {
        Order order = null;
        try {
            // 验证订单请求
            String validationError = validateOrderRequest(request);
            if (validationError != null) {
                return ResponseEntity.badRequest().body(validationError);
            }

            // 从对象池获取订单对象
            order = orderPool.borrowObject();

            // 设置订单信息
            order.setId(request.getOrderId());
            order.setSymbol(request.getSymbol());
            order.setSide(request.getSide());
            order.setType(request.getType());

            // 设置订单执行策略，默认为GTC
            if (request.getTimeInForce() != null) {
                order.setTimeInForce(request.getTimeInForce());
            } else {
                // 市价单默认IOC，限价单默认GTC
                if (request.getType() == Order.OrderType.MARKET) {
                    order.setTimeInForce(Order.TimeInForce.IOC);
                } else {
                    order.setTimeInForce(Order.TimeInForce.GTC);
                }
            }

            // 市价单不需要设置价格，限价单需要设置价格
            if (request.getType() == Order.OrderType.LIMIT) {
                order.setPrice(request.getPrice());
            } else {
                // 市价单价格设置为null或者BigDecimal.ZERO
                order.setPrice(BigDecimal.ZERO);
            }

            order.setQuantity(request.getQuantity());
            order.setFilledQuantity(BigDecimal.ZERO);
            order.setStatus(Order.OrderStatus.NEW);
            order.setUserId(request.getUserId());
            order.setCreateTime(LocalDateTime.now());
            order.setUpdateTime(LocalDateTime.now());

            // 发送订单到撮合引擎
            orderProducerService.sendOrder(order);

            log.info("订单已创建并发送到撮合引擎: {}, 类型: {}, 方向: {}, 执行策略: {}",
                    order.getId(), order.getType(), order.getSide(), order.getTimeInForce());

            return ResponseEntity.ok().body(order.getId());
        } catch (Exception e) {
            log.error("创建订单失败: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body("创建订单失败: " + e.getMessage());
        } finally {
            if (order != null) {
                orderPool.returnObject(order);
            }
        }
    }

    /**
     * 验证订单请求
     */
    private String validateOrderRequest(OrderRequest request) {
        if (request.getOrderId() == null || request.getOrderId().trim().isEmpty()) {
            return "orderId不能为空";
        }

        if (request.getSymbol() == null || request.getSymbol().trim().isEmpty()) {
            return "交易对不能为空";
        }

        if (request.getSide() == null) {
            return "订单方向不能为空";
        }

        if (request.getType() == null) {
            return "订单类型不能为空";
        }

        if (request.getQuantity() == null || request.getQuantity().compareTo(BigDecimal.ZERO) <= 0) {
            return "订单数量必须大于0";
        }

        if (request.getUserId() == null || request.getUserId().trim().isEmpty()) {
            return "用户ID不能为空";
        }

        // 验证订单ID格式（如果提供了的话）
        if (request.getOrderId() != null && !request.getOrderId().trim().isEmpty()) {
            String orderId = request.getOrderId().trim();
            if (orderId.length() > 50) {
                return "订单ID长度不能超过50个字符";
            }
            // 可以添加更多订单ID格式验证，比如只允许字母数字和连字符
            if (!orderId.matches("^[a-zA-Z0-9\\-_]+$")) {
                return "订单ID只能包含字母、数字、连字符和下划线";
            }
        }

        // 限价单必须有价格，且价格必须大于0
        if (request.getType() == Order.OrderType.LIMIT) {
            if (request.getPrice() == null || request.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
                return "限价单价格必须大于0";
            }
        }

        // 市价单不需要价格
        if (request.getType() == Order.OrderType.MARKET && request.getPrice() != null) {
            log.warn("市价单不需要价格参数，将忽略价格: {}", request.getPrice());
        }

        // 验证TimeInForce约束
        if (request.getTimeInForce() != null) {
            // 市价单只支持IOC
            if (request.getType() == Order.OrderType.MARKET &&
                    request.getTimeInForce() != Order.TimeInForce.IOC) {
                return "市价单只支持IOC执行策略";
            }
        }

        return null; // 验证通过
    }

    /**
     * 取消订单
     */
    @DeleteMapping("/{orderId}")
    @Timed(value = "api.order.cancel", description = "取消订单请求处理时间")
    public ResponseEntity<?> cancelOrder(@PathVariable String orderId, @RequestParam String userId, @RequestParam String symbol) {
        Order order = null;
        try {
            // 从对象池获取订单对象
            order = orderPool.borrowObject();

            // 设置取消订单信息
            order.setId(orderId);
            order.setUserId(userId);
            order.setSymbol(symbol);
            order.setStatus(Order.OrderStatus.CANCELED);
            order.setUpdateTime(LocalDateTime.now());

            // 发送取消订单请求到撮合引擎
            orderProducerService.sendCancelOrder(order);

            log.info("订单取消请求已发送: {}", orderId);

            return ResponseEntity.ok().body("订单取消请求已发送");
        } catch (Exception e) {
            log.error("取消订单失败: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body("取消订单失败: " + e.getMessage());
        } finally {
            if (order != null) {
                orderPool.returnObject(order);
            }
        }
    }
}